#!/usr/bin/perl -w
use strict;
use Getopt::Long;

#88888888888888888888888888888888888888888888888888888888888888888888888888888888

#	Usage

#88888888888888888888888888888888888888888888888888888888888888888888888888888888

my $usage = <<'USAGE';

USAGE:

    compare_sets.pl
				--1 file1
				--2 file2
                [--prefix output_file_prefix]
                [--col_header]
                [--verbose]
	
	Accepts pairs of files containing two sets of codes separated by new lines
	Prints out 3 files:
		1__only.list
		2__only.list
		1_and_2.list	
	The above file names can be prefixed by a supplied string
	--col_header indicates that the first row is the column header and should be ignored
USAGE


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

#	Get options

#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
# mandatory

# optional parameters
my $verbose;
my $prefix = '';
my $col_header;
my $file_1;
my $file_2;
my $help;
GetOptions(
			'verbose'			=> \$verbose,
			'1=s'				=> \$file_1,
			'2=s'				=> \$file_2,
			'prefix=s'			=> \$prefix,
			'col_header'		=> \$col_header,
			'help'				=> \$help);


die $usage if ($help);
die "Error:\nPlease supply the two files to be compared.\n".$usage
		unless ($file_1 and $file_2);

#-----------------------------------------------------------------------------------------
#	open files
#-----------------------------------------------------------------------------------------
sub file_open_failed($)
{
	die "Fatal Error:\nCould not open $_[0].\n$!\n";
}

open FILE_1, $file_1 or file_open_failed($file_1);
open FILE_2, $file_2 or file_open_failed($file_2);
open OUT_1, ">$prefix".'1__only.list' or file_open_failed(">$prefix".'1__only.list');
open OUT_2, ">$prefix".'2__only.list' or file_open_failed(">$prefix".'2__only.list');
open OUT_BOTH, ">$prefix".'1_and_2.list' or file_open_failed(">$prefix".'1_and_2.list');


#-----------------------------------------------------------------------------------------
#	get non-redundant first list
#-----------------------------------------------------------------------------------------
my @arr1 = <FILE_1>;
chomp @arr1;
@arr1 = grep { $_ ne '' } @arr1;
print STDERR "\t", scalar @arr1, "\titems read in $file_1\n"
	if ($verbose);
my %arr1;
@arr1{@arr1} = ();
print STDERR "\t", scalar keys %arr1, "\titems read in $file_1\n"
	if ($verbose && scalar keys %arr1 != scalar @arr1);

#-----------------------------------------------------------------------------------------
#	get non-redundant second list
#-----------------------------------------------------------------------------------------
my @arr2 = <FILE_2>;
chomp @arr2;
@arr2 = grep { $_ ne '' } @arr2;
print STDERR "\t", scalar @arr2, "\titems read in $file_2\n"
	if ($verbose);
my %arr2;
@arr2{@arr2} = ();
print STDERR "\t", scalar keys %arr2, "\titems read in $file_2\n"
	if ($verbose && scalar keys %arr2 != scalar @arr2);


my ($cnt_1) = 0;
my ($cnt_2) = 0;
my ($cnt_both) = 0;

# go through first list
for (keys %arr1)
{
	# also present in second, i.e. common to both
	if (exists $arr2{$_})
	{
		# mark items in the other list
		++$arr2{$_};
		print OUT_BOTH $_, "\n";
		++$cnt_both;
	}
	
	# not present in second, i.e. unique to 1
	else
	{
		print OUT_1 $_, "\n";
		++$cnt_1;
	}
}

# go through second list
for (keys %arr2)
{
	# not present in second, i.e. unique to 2
	unless (defined $arr2{$_})
	{
		print OUT_2 $_, "\n";
		++$cnt_2;
	}
}

if ($verbose)
{
	print STDERR "\t", $cnt_1,	"\titems only in the first file\n";
	print STDERR "\t", $cnt_both,	"\titems common to both\n";
	print STDERR "\t", $cnt_2,"\titems only in the second file\n";
}
